package com.rxh.controller;

import com.rxh.exception.PayException;
import com.rxh.pojo.payment.CrossCardInfo;
import com.rxh.pojo.payment.TradeObject;
import com.rxh.pojo.risk.RiskOrderTrack;
import com.rxh.service.PaymentService;
import com.rxh.service.RecordService;
import com.rxh.utils.GlobalConfiguration;
import com.rxh.utils.ParseTradeInfo;
import com.rxh.utils.SystemConstant;
import com.rxh.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * Created with IntelliJ IDEA.
 * User: 陈俊雄
 * Date: 2018/8/21
 * Time: 9:20
 * Project: Management
 * Package: com.rxh.controller
 */

@Controller
public class PaymentController {
    private final PaymentService paymentService;

    private final GlobalConfiguration globalConfiguration;

    private final RecordService recordService;

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    public PaymentController(PaymentService paymentService, GlobalConfiguration globalConfiguration, RecordService recordService) {
        this.paymentService = paymentService;
        this.globalConfiguration = globalConfiguration;
        this.recordService = recordService;
    }

    /**
     * 内嵌交易
     *
     * @param req       http请求
     * @param tradeInfo 交易信息（Xml报文进行Base64加密）
     * @return 交易结果
     * @throws PayException 支付异常信息
     */
    @RequestMapping(value = "/inline_pay")
    @ResponseBody
    public String inlinePay(HttpServletRequest req, String tradeInfo) throws PayException {
        RiskOrderTrack orderTrack = null;
        try {
            req.getSession().setAttribute("interface", SystemConstant.INTERFACE_INNER);
            orderTrack = getOrderTrack(req, tradeInfo, SystemConstant.INTERFACE_INNER);
            return paymentService.inlinePayment(orderTrack, ParseTradeInfo.parse(tradeInfo, orderTrack));
        } finally {
            recordService.saveOrderTrack(orderTrack);
        }
    }

    /**
     * 返回跳转交易页面
     *
     * @param req       http请求
     * @param tradeInfo 交易信息（Xml报文进行Base64加密，切换语言时无值）
     * @param locale    切换语言时有值
     * @return 国际化跳转交易页面
     * @throws PayException 支付异常信息
     */
    @RequestMapping(value = "/cross_pay")
    public String crossPayPage(HttpServletRequest req, String tradeInfo, String locale) throws PayException {
        RiskOrderTrack orderTrack = null;
        try {
            req.getSession().setAttribute("interface", SystemConstant.INTERFACE_REDIRECT);
            if (StringUtils.isNotBlank(tradeInfo)) {
                orderTrack = getOrderTrack(req, tradeInfo, SystemConstant.INTERFACE_REDIRECT);
                TradeObject tradeObject = ParseTradeInfo.parse(tradeInfo, orderTrack);
                req.getSession().setAttribute("orderTrack", orderTrack);
                req.getSession().setAttribute("tradeObject", tradeObject);
                req.getSession().setAttribute("year", Calendar.getInstance().get(Calendar.YEAR));
                locale = tradeObject.getLang();
            }
            String[] lang = StringUtils.isNotBlank(locale) ? locale.split("_") : new String[0];
            switch (lang.length) {
                case 1:
                    req.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, new Locale(lang[0]));
                    break;
                case 2:
                    req.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, new Locale(lang[0], lang[1]));
                    break;
                default:
                    req.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, Locale.ENGLISH);
                    break;
            }
            return "credit/moto";
        } finally {
            recordService.saveOrderTrack(orderTrack);
        }
    }

    /**
     * 进行跳转交易
     *
     * @param req           http请求
     * @param crossCardInfo 持卡人信息
     * @return 交易结果页面
     * @throws PayException 支付异常信息
     */
    @RequestMapping(value = "/cross_payment")
    public String crossPay(HttpServletRequest req, CrossCardInfo crossCardInfo) throws PayException {
        RiskOrderTrack orderTrack = null;
        try {
            orderTrack = (RiskOrderTrack) req.getSession().getAttribute("orderTrack");
            orderTrack.setStatus(SystemConstant.PAY_STATUS_PAGE);
            TradeObject tradeObject = (TradeObject) req.getSession().getAttribute("tradeObject");
            ParseTradeInfo.parse(crossCardInfo, tradeObject);
            req.getSession().setAttribute("crossResult", paymentService.crossPayment(orderTrack, tradeObject));
            return "pay/result";
        } finally {
            recordService.saveOrderTrack(orderTrack);
        }
    }

    private RiskOrderTrack getOrderTrack(HttpServletRequest req, String tradeInfo, short interType) throws PayException {
        if (globalConfiguration.isProduction() && req.getRemotePort() != 80) {
            logger.error("服务器端口非法端！当前端口：" + req.getServerPort());
            throw new PayException("服务器端口非法端！当前端口：" + req.getServerPort(), 1400);
        }
        String reqUrl = req.getHeader(HttpHeaders.REFERER) == null ?
                req.getRequestURL().toString() :
                req.getHeader(HttpHeaders.REFERER);
        if (StringUtils.isBlank(tradeInfo)) {
            logger.error("提交参数为空！");
            logger.info("来源站点：" + reqUrl + "，IP：" + req.getRemoteHost());
            throw new PayException("提交参数为空！", 1000);
        }
        RiskOrderTrack orderTrack = new RiskOrderTrack();
        orderTrack.setTradeTime(new Date());
        orderTrack.setIp(req.getRemoteHost());
        orderTrack.setScheme(req.getScheme());
        orderTrack.setStatus(SystemConstant.PAY_STATUS_GATEWAY);
        orderTrack.setRefer(reqUrl);
        orderTrack.setInterType(interType);
        return orderTrack;
    }
}